#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import uuid
import threading
from PySide6.QtCore import QThreadPool, QMutex, QObject
from .download_task import DownloadTask, DownloadStatus


class TaskManager:
    """下载任务管理器，负责管理和调度所有下载任务"""
    
    def __init__(self, max_concurrent=10):
        """
        初始化任务管理器
        
        Args:
            max_concurrent: 最大并发下载任务数
        """
        self.max_concurrent = max_concurrent
        self.thread_pool = QThreadPool.globalInstance()
        self.thread_pool.setMaxThreadCount(max_concurrent + 2)  # 额外的线程用于其他任务
        
        self.tasks = {}  # 存储所有任务 {task_id: task}
        self.running_tasks = set()  # 正在运行的任务ID
        self.waiting_tasks = []  # 等待中的任务ID队列
        
        # 用于线程同步
        self.mutex = QMutex()
        
        # 信号连接标记，避免重复连接
        self.signals_connected = False
        
        self.signals = None
    
    def set_signals(self, signals):
        """设置信号对象，用于任务通信"""
        self.signals = signals
        
        # 连接信号
        if self.signals and not self.signals_connected:
            self.signals.task_completed.connect(self._on_task_completed)
            self.signals.task_failed.connect(self._on_task_failed)
            self.signals_connected = True
    
    def add_task(self, url, save_path):
        """
        添加下载任务
        
        Args:
            url: m3u8链接
            save_path: 保存路径
            
        Returns:
            task_id: 任务ID
        """
        # 生成唯一任务ID
        task_id = str(uuid.uuid4())
        task = DownloadTask(task_id, url, save_path, self.signals)
        
        # 线程安全地添加任务
        self.mutex.lock()
        self.tasks[task_id] = task
        self.waiting_tasks.append(task_id)
        self.mutex.unlock()
        
        return task_id
    
    def start_task(self, task_id):
        """
        开始指定任务
        
        Args:
            task_id: 任务ID
        """
        self.mutex.lock()
        
        if task_id not in self.tasks:
            self.mutex.unlock()
            return
        
        task = self.tasks[task_id]
        
        # 如果任务已经在运行，不做处理
        if task_id in self.running_tasks:
            self.mutex.unlock()
            return
        
        # 如果已经达到最大并发数，加入等待队列
        if len(self.running_tasks) >= self.max_concurrent:
            if task_id not in self.waiting_tasks:
                self.waiting_tasks.append(task_id)
            self.mutex.unlock()
            return
        
        # 从等待队列中移除（如果存在）
        if task_id in self.waiting_tasks:
            self.waiting_tasks.remove(task_id)
        
        # 加入运行队列并启动
        self.running_tasks.add(task_id)
        self.mutex.unlock()
        
        # 启动任务（在锁外执行，避免死锁）
        self.thread_pool.start(task)
    
    def pause_task(self, task_id):
        """
        暂停指定任务
        
        Args:
            task_id: 任务ID
        """
        self.mutex.lock()
        
        if task_id not in self.tasks:
            self.mutex.unlock()
            return
        
        task = self.tasks[task_id]
        
        # 如果任务正在运行，则暂停
        if task_id in self.running_tasks:
            self.running_tasks.remove(task_id)
            # 先解锁再暂停，避免死锁
            self.mutex.unlock()
            task.pause()
        else:
            # 如果任务在等待队列中，则移除
            if task_id in self.waiting_tasks:
                self.waiting_tasks.remove(task_id)
            self.mutex.unlock()
    
    def resume_task(self, task_id):
        """
        恢复指定任务
        
        Args:
            task_id: 任务ID
        """
        self.mutex.lock()
        
        if task_id not in self.tasks:
            self.mutex.unlock()
            return
        
        # 重新添加到等待队列
        if task_id not in self.waiting_tasks and task_id not in self.running_tasks:
            self.waiting_tasks.append(task_id)
        
        self.mutex.unlock()
        
        # 尝试启动任务
        self._start_waiting_tasks()
    
    def remove_task(self, task_id):
        """
        移除指定任务
        
        Args:
            task_id: 任务ID
        """
        self.mutex.lock()
        
        if task_id not in self.tasks:
            self.mutex.unlock()
            return
        
        # 如果任务正在运行，先暂停
        if task_id in self.running_tasks:
            self.running_tasks.remove(task_id)
            task = self.tasks[task_id]
            # 先解锁再暂停，避免死锁
            self.mutex.unlock()
            task.pause()
            self.mutex.lock()
        
        # 如果任务在等待队列中，移除
        if task_id in self.waiting_tasks:
            self.waiting_tasks.remove(task_id)
        
        # 移除任务
        del self.tasks[task_id]
        self.mutex.unlock()
    
    def start_all_tasks(self):
        """开始所有任务"""
        self.mutex.lock()
        
        # 将所有非运行任务加入等待队列
        for task_id in list(self.tasks.keys()):
            if task_id not in self.waiting_tasks and task_id not in self.running_tasks:
                self.waiting_tasks.append(task_id)
        
        self.mutex.unlock()
        
        # 尝试启动等待中的任务
        self._start_waiting_tasks()
    
    def pause_all_tasks(self):
        """暂停所有任务"""
        self.mutex.lock()
        
        # 记录需要暂停的任务
        tasks_to_pause = list(self.running_tasks)
        # 清空运行队列和等待队列
        self.running_tasks.clear()
        self.waiting_tasks.clear()
        
        self.mutex.unlock()
        
        # 在锁外执行暂停操作，避免死锁
        for task_id in tasks_to_pause:
            if task_id in self.tasks:
                self.tasks[task_id].pause()
    
    def _on_task_completed(self, task_id):
        """
        任务完成回调
        
        Args:
            task_id: 任务ID
        """
        self.mutex.lock()
        
        if task_id in self.running_tasks:
            self.running_tasks.remove(task_id)
        
        self.mutex.unlock()
        
        # 启动下一个任务
        self._start_waiting_tasks()
    
    def _on_task_failed(self, task_id, error_msg):
        """
        任务失败回调
        
        Args:
            task_id: 任务ID
            error_msg: 错误信息
        """
        self.mutex.lock()
        
        if task_id in self.running_tasks:
            self.running_tasks.remove(task_id)
        
        self.mutex.unlock()
        
        # 启动下一个任务
        self._start_waiting_tasks()
    
    def _start_waiting_tasks(self):
        """启动等待中的任务"""
        while True:
            self.mutex.lock()
            
            # 检查是否有空闲槽位和等待任务
            if len(self.running_tasks) >= self.max_concurrent or not self.waiting_tasks:
                self.mutex.unlock()
                break
            
            # 获取下一个任务ID并从等待队列移除
            task_id = self.waiting_tasks.pop(0)
            
            # 标记为运行中
            if task_id in self.tasks:
                self.running_tasks.add(task_id)
                task = self.tasks[task_id]
                self.mutex.unlock()
                
                # 在锁外启动任务，避免死锁
                self.thread_pool.start(task)
            else:
                self.mutex.unlock() 